﻿<?php

/**
 * \View
 * 实现了一个静态方法make，接受视图名称作为参数，以.作为目录的间隔符
 * make静态方法会检查视图名称是否为空，检查视图文件是否存在，并给出相应的异常
 * 视图名称合法且文件存在时，实例化一个View类的对象返回
 * 使用with('key',$value)或者优雅的withKey($value)来给这个View对象插入要在视图里调用的变量
 * withFuckMe($value)将采用蛇形命名法被转化成$fuck_me供视图使用
 * 最终组装好的View对象会被赋给HomeController的成员变量$view，这个变量是从BaseController中继承得来
 * 父类BaseController中的析构函数__destruct()将在function home()执行完成后处理这个成员变量：extract出视图要用到的变量，require视图文件，将最终运算结果发送给浏览器，流程结束
 */
class View
{
    const VIEW_BASE_PATH = '/app/views/';

    public $view;
    public $data;

    public function __construct($view)
    {
        $this->view = $view;
    }

    public static function make($viewName = null)
    {
        if (!$viewName) {
            throw new InvalidArgumentException("视图名称不能为空！");
        } else {

            $viewFilePath = self::getFilePath($viewName);
            if (is_file($viewFilePath)) {
                return new View($viewFilePath);
            } else {
                throw new UnexpectedValueException("视图文件不存在！");
            }
        }
    }

    public function with($key, $value = null)
    {
        $this->data[$key] = $value;
        return $this;
    }

    private static function getFilePath($viewName)
    {
        $filePath = str_replace('.', '/', $viewName);
        return BASE_PATH . self::VIEW_BASE_PATH . $filePath . '.php';
    }

    public function __call($method, $parameters)
    {
        if (starts_with($method, 'with')) {
            return $this->with(snake_case(substr($method, 4)), $parameters[0]);
        }

        throw new BadMethodCallException("方法 [$method] 不存在！.");
    }
}